/*
 * Copyright (c) 2025 Huawei Device, Inc. Ltd. and <马弓手>.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef CORDOVA_VIEW_CONTROLLER_H
#define CORDOVA_VIEW_CONTROLLER_H

#include "ConfigXmlParser.h"
#include "CordovaBridge.h"
#include "PluginEntry.h"
#include "CordovaWebViewEngine.h"

/**
 * @brief defines all resource control classes for the Cordova C++ side.
 * Registers objects and creates plugin instances during WebView initialization.
 * Destroys related objects during WebView destruction.
 */
class CordovaViewController {
    static const unsigned int LOG_PRINT_DOMAIN;
    /**JavaScript execution queue object. All WebViews share a single queue.*/
    NativeToJsMessageQueue* m_queue;
    /**
     * Plugin management object
     * Manages all C++ side plugins (each C++ plugin shares one object across all WebViews).
     * Manages all ArkTS side plugins (maintains one object per plugin name; the ArkTS side distinguishes plugins when called from C++).
     * It is recommended to maintain only one TsCordovaPlugin object on the C++ side in future versions.
     */
    PluginManager* m_pluginManager;
    /**
     * JavaScript-to-C++ bridge object, primarily used to invoke specific plugin methods.
     * All WebViews share this object. The actual bridging is handled by the Engine.
     * HarmonyOS uses JS_OBJECT bridge mode for JavaScript-to-C++ communication.
     */
    CordovaBridge* m_bridge;
    /**Parses config.xml. All WebViews share a single instance of this object.*/
    ConfigXmlParser* m_xmlParser;
    /**
     * Stores the JS API and Engine instances associated with a WebView.
     * These are destroyed when the WebView is destroyed.
     */
    map<string, CordovaExposedJsApi*> m_mapWebTagJsApi;
    map<string, CordovaWebViewEngine*> m_mapWebTagEngine;
    
    class CheckCertificates :public CThread {
        string m_strBundleName;
        string m_strAppId;
        bool checkCert(void* pX509);
    public:
        void Execute(void *);
    };
    CheckCertificates m_checkCertificate;
public:
    CordovaViewController();
    ~CordovaViewController();
    /**
     * @brief Loads the config.xml configuration file.
     */
    void loadConfig();
    /**
     * @brief Cordova initialization function.
     * @param strWebTag Web tag string.
     */
    void init(const string & strWebTag);
    /**
     * @brief Function executed before the page is displayed.
     * @param strWebTag Web tag string.
     */
    void loadUrl(const string & strWebTag);
    /**
     * @brief Returns the config.xml property configuration object.
     * @return Preferences object
     */
    CordovaPreferences* getCordovaPreferences();
    /**
     * @brief Sets the WebView callback function.
     * @param engine JavaScript-to-C++ engine.
     * @param strWebTag Web tag string.
     */
    void SetComponentCallback(CordovaWebViewEngine* engine, const string & strWebTag);
    /**
     * @brief Notifies the C++ plugin of the execution result from the ArkTS side, allowing the C++ side to complete subsequent tasks.
     * @param strWebTag Web tag string
     * @param pluginName Plugin name.
     * @param strAction Action string.（usually "onArKTsResult" when ArkTS notifies the C++ plugin）
     * @param strArgs Argument string.
     */
    void execPluginResult(const string& strWebTag, const string& pluginName, const string& strAction, const string& strArgs);
    /**
     * @brief Triggered when WebView's onControllerAttached is called. Initializes corresponding objects on the C++ side.
     * @param webTag Web tag string.
     * @param userData User data, typically a pointer to the CordovaWebViewEngine object.
     */
    static void onWebControllerAttached(const char *webTag, void *userData);
    /**
     * @brief Triggered when the web page starts loading on the C++ side (Web lifecycle function). Typically uses the corresponding function on the ArkTS side.
     * @param webTag Web tag string.
     * @param userData User data, typically a pointer to the CordovaWebViewEngine object.
     */
    static void onWebPageBegin(const char *webTag, void *userData);
    /**
     * @brief Triggered when the web page finishes loading on the C++ side (Web lifecycle function). Typically uses the corresponding function on the ArkTS side.
     * @param webTag webTag Web tag string.
     * @param userData User data, typically a pointer to the CordovaWebViewEngine object.
     */
    static void onWebPageEnd(const char *webTag, void *userData);
    /**
     * @brief Triggered when the WebView is destroyed on the C++ side. Destroys the corresponding objects associated with the WebView.
     * @param webTag webTag Web tag string.
     * @param userData User data, typically a pointer to the CordovaWebViewEngine object.
     */
    static void onWebDestroy(const char *webTag, void *userData);
    /**
     * @brief Retrieves the CordovaWebViewEngine based on the web tag.
     * @param strWebTag web tag string 
     * @return CordovaWebViewEngine pointer
     */
    CordovaWebViewEngine* getCordovaWebViewEngine(const string & strWebTag);
    vector<PluginEntry>* getPluginEntry();
    void instantiateTsPlugin(const string& strWebTag, cJSON* pJson);
    void addJavaScript(const string& strWebTag, const string& statement);
    vector<string>* getHostName();
    vector<string>* getConfigHostName();
    vector<string>* getProtocolUrl();
    string getChcpConfigUrl();
    bool getAllAllowUpdatesAutoDownload();
    bool getAllowUpdatesAutoInstall();
    int getActiveInterfaceVersion();
    void getCameraImageCompress(bool& isCameraImageCompress, long & lngCompressImageSize, string& strCameraCompressShowToast);
    PluginManager* getPluginManager();
    long getCordovaCacheDuration();
    string getIonicHostName();
    string getIonicScheme();
};
#endif